package de.gameduell.framework.queue {
	import de.gameduell.framework.debug.Debug;
	import de.gameduell.framework.queue.IAction;
	import de.gameduell.framework.queue.Delay;
	
	import flash.events.TimerEvent;
	import flash.utils.Timer;	

	/**
	 * ActionQueue to keep function in the right order.
	 * Helpfull for events which causes an animation.
	 * 
 	 * @deprecated - please use an IGDAction instead
	 */
	public class ActionQueue {
		
		private static var DEFAULT_TIMEOUT:int = 13000;
		private var queue:Array;
		private var performingAction:Boolean;
		private var queueTimer:Timer;
		private var _queueTimeout:Number;
		private var history:Array;
		private var deadlockDetected:Boolean;

		/**
		 * Constructor - setup the deadlock-detection timer.
		 * You can also adjust this timer value manually.
		 */
		public function ActionQueue() {
			queue 	  = new Array();
			history = new Array();
			deadlockDetected = false;
			performingAction = false;
			queueTimer = new Timer(DEFAULT_TIMEOUT, 1);
			queueTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timeout);
			queueTimer.stop();
		}
	
		/**
		 * Adds an action which needs to be queued. Only the first action of the queue
		 * will start automatically. Stacked action will be executed after the application
		 * has called <b>checkActionQueue()</b>.
		 * 
		 * @param action		function to be queued
		 * @param arguments		arguments for the function
		 * @param description	optional - needed if you want to read the queue history
		 */
		public function addAction(aAction:Function, aArguments:Array, aDescription:String = "none"):void {
			addIAction(new Action(aAction, aArguments, aDescription));
		}
			
		public function addDelay(aDelay:Number,aDescription:String = null):void{
			addIAction(new Delay(aDelay,aDescription,this));
		}
		
		public function addIAction(aIAction:IAction):void{
			queue.push(aIAction);
//			Debug.trace("ActionQueue::addIAction "+aIAction.description+" performingAction? "+performingAction);

			if(queue.length == 1 && !performingAction){
				checkActionQueue();
			}
		}
		
		/**
		 * After an action is done, the application have to call this function.
		 * Otherwise it will cause a deadlock.
		 */
		public function checkActionQueue():void {
			queueTimer.stop();
			if(queue.length > 0){	
				performingAction = true;	
				var nextAction:IAction = IAction(queue.shift());
				history.push(nextAction);
				queueTimer.start();
				nextAction.compute();
			}else{
//				Debug.trace("ActionQueue::checkActionQueue: last action done");
				performingAction = false;
			}
		}

		/**
		 * Sets a user defined timeout to detect a deadlock.
		 * @param timeout	a new timeout
		 */
		public function set queueTimeout(timeout:int):void {
			_queueTimeout    = timeout;
			queueTimer.delay = timeout;
		}
		
		/**
		 * Can call a defined callback (e.g. the main application) to
		 * handle this state. Is working only once.
		 * If it is no real deadlock (due to connection retries, ..),
		 * the actionQueue will work further on.
		 */
		private function timeout(event:TimerEvent):void {
			if(!deadlockDetected){
				deadlockDetected = true;
			}
		}
	}

}
